﻿using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ABAssetBundle:IAssetBundle
{
    private string _bundleName = null;
    private AssetBundle _ab = null;
    private int refCount = 0;
    private List<IAssetBundle> _refABList = null;
    private AssetBundleCreateRequest _abRequest = null;
    private Action _callback = null;

    private ABLoader _abLoader;
    public ABAssetBundle(ABLoader abLoader)
    {
        _abLoader = abLoader;
    }

    public void CreateRes(string bundleName, Action callback)
    {
        _bundleName = bundleName;
        _callback = callback;
        CreateRes(bundleName);
    }


    public void CreateRes(string bundleName)
    {
        _bundleName = bundleName;
        string[] strs = _abLoader.GetAllDependencies(bundleName);
        if (strs == null || strs.Length == 0)
        {
            //不需要加载依赖文件
            string path = IO.GetResPath(bundleName);
            Debug.Log("=====>>path：" + path);
            _abRequest = AssetBundle.LoadFromFileAsync(path);
        }
        else
        {
            //需要加载依赖文件
            for (int i = 0; i < strs.Length; i++)
            {
                //检查该资源是否已经加载
                ABAssetBundle tempIab = _abLoader.GetIAssetBundle(strs[i]) as ABAssetBundle;
                if (tempIab == null)
                {
                    ABAssetBundle iab = new ABAssetBundle(_abLoader);
                    iab.CreateRes(strs[i]);
                    if (_refABList == null)
                    {
                        _refABList = new List<IAssetBundle>();
                    }
                    _refABList.Add(iab);
                }
                else
                {
                    //引用次数加1
                    tempIab.AddReferenceCount();
                }
            }
            string path = IO.GetResPath(bundleName);
            //Debug.Log("=====>???>path：" + path);
            _abRequest = AssetBundle.LoadFromFileAsync(path);
        }
    }

    public void AddReferenceCount()
    {
        if(_refABList != null)
        {
            for (int i = 0; i < _refABList.Count; i++)
            {
                _refABList[i].AddReferenceCount();
            }
        }
        ++refCount;
    }

    public bool IsDone()
    {
        bool isDone = true;
        //先加载依赖资源
        if(_refABList != null && _refABList.Count > 0 )
        {
            for (int i = 0; i < _refABList.Count; i++)
            {
                if(!_refABList[i].IsDone())
                {
                    isDone = false;
                    break;
                }
            }
        }
        if(isDone)
        {
            if(_abRequest != null && _abRequest.isDone)
            {
                _ab = _abRequest.assetBundle;
                ++refCount;
                _abLoader.AddAssetBundle(_bundleName, this);
                if (_callback != null)
                {
                    _callback();
                }
                return _abRequest.isDone;
            }
        }
        return false;
    }

    public T LoadRes<T>(string assetName) where T : UnityEngine.Object
    {
        if (_ab != null)
        {
            T t = _ab.LoadAsset<T>(assetName);
            if (t == null)
            {
                Debug.LogError("!!资源加载失败：" + assetName);
            }
            else
            {
                return t;
            }
        }
        return default(T);
    }

    public int ReferenceCount()
    {
        return refCount;
    }

    public void ReleaseRes()
    {
        if (_refABList != null)
        {
            for (int i = 0; i < _refABList.Count; i++)
            {
                _refABList[i].ReleaseRes();
            }
        }
        SubReferenceCount();
    }

    public void UnLoadAB()
    {
        refCount = 0;
        _refABList = null;
        _abLoader = null;
        _ab.Unload(false);
        Debug.Log("======unload:" + _bundleName);
        _ab = null;
        LoadManager.Instance.UnLoadAB(_bundleName);
        _bundleName = null;
    }

    public void SubReferenceCount()
    {
        --refCount;
        if (refCount <= 0)
        {
            UnLoadAB();
        }
    }

    public string GetABName()
    {
        if (_ab == null)
        {
            return null;
        }
        return _ab.name;
    }

    public AssetBundle GetAssetBundle()
    {
        return _ab;
    }


}
